<?php
namespace Common\Common;

use Think\Exception;
use Think\Log;
use Think\Model;

/**
 * @name
 * @author lihui
 * @since  2015年7月28日 下午3:09:50
 * @version 1.0
 * @copyright vanke
 */
class Tools
{

    public static function https_request($url, $data, $type = 'GET', $encoding = 'UTF-8')
    {
        $curl = curl_init();
        //https option
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

        if (!is_array($data) && strtoupper($type) === 'GET') {
            return 'data required array';
        }

        $this_header = array(
            "Content-type:application/x-www-form-urlencoded;Charset=$encoding"
        );

        $_data = http_build_query($data);

        curl_setopt($curl, CURLOPT_HTTPHEADER, $this_header);

        if (strcmp(strtoupper($type), 'POST') == 0) {
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        } else {
            curl_setopt($curl, CURLOPT_URL, $url . '?' . $_data);
            curl_setopt($curl, CURLOPT_HEADER, false);
        }

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($curl);

        if (curl_errno($curl)) {
            return 'Errno' . curl_error($curl);
        }
        curl_close($curl);
        return $result;
    }

    /**
     * 通过CURL方式去请求 接口
     * @param $url 接口地址
     * $SecretKey 秘钥
     * @param $data  请求的参数 数组
     * @param string $type 请求的方式
     * @param string $encoding 请求发送的编码
     * @return mixed|string
     */
    public static function http_request($url, $data, $type = 'GET', $encoding = 'UTF-8')
    {

        $curl = curl_init();
        if (!is_array($data) && strtoupper($type) === 'GET') {
            return 'data required array';
        }

        $this_header = array(
            "Content-type:application/x-www-form-urlencoded;Charset=$encoding"
        );

        $_data = http_build_query($data);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $this_header);

        if (strcmp(strtoupper($type), 'POST') == 0) {
            curl_setopt($curl, CURLOPT_URL,$url);
            curl_setopt($curl, CURLOPT_POST, TRUE);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $_data);
        } else {
            curl_setopt($curl, CURLOPT_URL,$url . '?' . $_data);
            curl_setopt($curl, CURLOPT_HEADER, false);
        }

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($curl);

        if (curl_errno($curl)) {
            return 'Errno' . curl_error($curl);
        }
        curl_close($curl);
        return $result;

    }

    /**
     * 使用POST方式调用接口
     * @param $url 接口地址
     * @param $data 要传的json数据
     * @return mixed|string 返回值
     * @author  lihui<yezhimeih7@foxmail.com>
     */
    public static function http_request_post($url, $data)
    {
        $curl = curl_init();
        $this_header = array(
            "Content-type:application/x-www-form-urlencoded;Charset=UTF-8"
        );
        curl_setopt($curl, CURLOPT_HTTPHEADER, $this_header);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, TRUE);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($curl);

        if (curl_errno($curl)) {
            return 'Errno' . curl_error($curl);
        }
        curl_close($curl);
        return $result;
    }


    /**
     * 以post方式提交xml到对应的接口url
     *
     * @param string $xml 需要post的xml数据
     * @param string $url url
     * @param bool $useCert 是否需要证书，默认不需要
     * @param int $second url执行超时时间，默认30s
     * @return mixed
     * @throws WxPayException
     */
    public static function postXmlCurl($xml, $url, $useCert = false, $second = 30)
    {
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);

        //如果有配置代理这里就设置代理
//        if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
//            && WxPayConfig::CURL_PROXY_PORT != 0){
//            curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);
//            curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);
//        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);//严格校验
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

//        if($useCert == true){
//            //设置证书
//            //使用证书：cert 与 key 分别属于两个.pem文件
//            curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
//            curl_setopt($ch,CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);
//            curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
//            curl_setopt($ch,CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);
//        }

        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            throw new Exception("curl出错，错误码:$error");
        }
    }


    /**
     * 记录debug的日志
     * @param unknown $message
     * @param string $level
     */
    public static function LogForDebug($message, $level = 'INFO')
    {

        Log::write($message, $level, '', C('LOG_PATH') . date('y_m_d') . '_debug.log');

    }

    /**
     * 计算中文字符的长度
     * @param $str
     * @return int
     */
    public static function absLength($str)
    {
        if (empty($str)) {
            return 0;
        }
        if (function_exists('mb_strlen')) {
            return mb_strlen($str, 'utf-8');
        } else {
            preg_match_all("/./u", $str, $ar);
            return count($ar[0]);
        }
    }

    /**
     * 生成UUID
     * @param string $str
     * @return string
     */
    public static function generateUUID($str = '')
    {
        $charid = strtoupper(md5(uniqid($str . mt_rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = substr($charid, 0, 8) . $hyphen
            . substr($charid, 8, 4) . $hyphen
            . substr($charid, 12, 4) . $hyphen
            . substr($charid, 16, 4) . $hyphen
            . substr($charid, 20, 12);
        return $uuid;
    }

    /**
     * 生成随机数
     * @param number $length
     */
    public static function getRandomStr($length = 15)
    {
        $text = 'abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ123456789';
        //$text = '0123456789';
        $str = '';
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($text, mt_rand(0, strlen($text) - 1), 1);
        }
        return $str;
    }

    public static function weixinpayOrdering($out_trade_no,$total_fee,$body,$product_id){
        ini_set('date.timezone','Asia/Shanghai');

        require_once SITE_PATH."/wxpay/lib/WxPay.Api.php";
        require_once SITE_PATH."/wxpay/example/WxPay.NativePay.php";
        require_once SITE_PATH.'/wxpay/example/log.php';

        $notify = new \NativePay();

//模式二
        /**
         * 流程：
         * 1、调用统一下单，取得code_url，生成二维码
         * 2、用户扫描二维码，进行支付
         * 3、支付完成之后，微信服务器会通知支付成功
         * 4、在支付成功通知中需要查单确认是否真正支付成功（见：notify.php）
         */
        $out_trade_no=$out_trade_no."_".date("YmdHis");
        $total_fee=$total_fee*100;
        $input = new \WxPayUnifiedOrder();
        $input->SetBody($body);
        $input->SetAttach("通润宝");
        $input->SetOut_trade_no($out_trade_no);
        $input->SetTotal_fee($total_fee);
//        $input->SetTotal_fee("1");
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("交易券");
        $input->SetNotify_url("http://www.tongrb.com/Orders/PayNotify/weixinNotify");
        $input->SetTrade_type("NATIVE");
        $input->SetProduct_id($product_id);
        $result = $notify->GetPayUrl($input);
        return $url2 = $result["code_url"];
    }

    /**
     * 支付宝下单,网页版的及时到账
     * @param string $out_trade_no 外部订单号(本系统)
     * @param string $subject  摘要,不能超过32个字
     * @param string $total_fee 总共的费用
     * @param string $body 详细描述
     * @return  string 返回支付宝的网页
     */
    public static function alipayOrdering($out_trade_no,$subject,$total_fee,$body){
        $url = sp_get_host() . "/alipay/alipayapi.php";
        $alipay_data = array(
            'WIDout_trade_no' => $out_trade_no,
            'WIDsubject' => $subject,
            'WIDtotal_fee' => $total_fee,
            'WIDbody' => $body,
        );
        return Tools::http_request($url, $alipay_data, 'POST');
    }


    public static function alipayNotify($func){

        require_once(SITE_PATH."/alipay/alipay.config.php");
        require_once(SITE_PATH."/alipay/lib/alipay_notify.class.php");

//计算得出通知验证结果
        $alipayNotify = new AlipayNotify($alipay_config);
        $verify_result = $alipayNotify->verifyNotify();

        if($verify_result) {//验证成功
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //请在这里加上商户的业务逻辑程序代


            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

            //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表

            //商户订单号

            $out_trade_no = $_POST['out_trade_no'];
            $out_trade_no=intval($out_trade_no);
            //支付宝交易号

            $trade_no = $_POST['trade_no'];

            //交易状态
            $trade_status = $_POST['trade_status'];


            if($_POST['trade_status'] == 'TRADE_FINISHED') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序
                $func($out_trade_no,$trade_no);

                //注意：
                //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知

                //调试用，写文本函数记录程序运行情况是否正常
                //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
            }
            else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序
                $ordersModel->where(array('id'=>intval($_POST['out_trade_no'])))->save(array('status'=>1));
                //注意：
                //付款完成后，支付宝系统发送该交易状态通知

                //调试用，写文本函数记录程序运行情况是否正常
                //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
            }

            //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

            echo "success";		//请不要修改或删除

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        }
        else {
            //验证失败
            echo "fail";

            //调试用，写文本函数记录程序运行情况是否正常
            //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");

        }
    }

}

?>